#include "ChademoLogicProcess.h"
#include "string.h"
#include "stdio.h"
#include "chargeCtrl.h"
#include "outputCtl.h"
#include "inputCtl.h"
#include "uuPowerProcess.h"
#include "ChademoSendProcess.h"
#include "ChademoReceiveProcess.h"
#include "ccsLogicProcess.h"
extern messageQueue plc232_RxQue[]; 		//plc串口接收队列

/*
 * send functions list:
 * 1.CHAdeMO_ReportInitReq
 * 2.CHAdeMO_StartReq
 * 3.CHAdeMO_AllStopReq
 * 4.CHAdeMO_ReportStateReq
 * 5.CHAdeMO_SessionSetupRes
 * 6.CHAdeMO_ChargeParameterDiscoveryRes
 * 7.CHAdeMO_CableCheckRes		
 * 8.CHAdeMO_PowerDeliveryRes
 * 9.CHAdeMO_CurrendDemandRes
 * 10.CHAdeMO_WeldingDetectionRes	
 * 11.CHAdeMO_SessionStopRes
 */
 
/*
 * message reception analysis functions list:
 * 1.CHAdeMO_ReportInitMsg_Analyse
 * 2.CHAdeMO_ReportSLACMsg_Analyse
 * 3.CHAdeMO_ReportSDPMsg_Analyse
 * 4.CHAdeMO_ReportV2GCHAMsg_Analyse/CHAdeMO/AC
 * 5.CHAdeMO_AllStopMsg_Analyse
 * 6.CHAdeMO_ReportStateMsg_Analyse
 * 7.CHAdeMO_SessionSetupMsg_Analyse
 * 8.CHAdeMO_ChargeParameterDiscoveryMsg_Analyse
 * 9.CHAdeMO_CableCheckMsg_Analyse
 * 10.CHAdeMO_PowerDeliveryMsg_Analyse
 * 11.CHAdeMO_CurrendDemandMsg_Analyse
 * 12.CHAdeMO_WeldingDetectionMsg_Analyse
 * 13.CHAdeMO_SessionStopMsg_Analyse
 */

RNL_CHAdeMOEvsePara rnlChademoEvsePara[GUNNUM_MAX];
RNL_CHAdeMOEvccPara rnlChademoEvccPara[GUNNUM_MAX];
RNL_CHAdeMOCommunicationCtrlS rnlChademoCommCtrl[GUNNUM_MAX];
 
void CHAdeMO_232_TxData_Init(RNL_CHAdeMOEvsePara *p_tx);//evse充电参数结构体初始化
void CHAdeMO_232_RxData_Init(RNL_CHAdeMOEvccPara *p_rx);//secc充电参数结构体初始化
void CHAdeMO_232_TRCtrl_Init(RNL_CHAdeMOCommunicationCtrlS *trCtrl);//与plc通讯控制结构体初始化

 
 
void RNL_CHAdeMOCommunicationInit(uint8_t gunId)
{
	uint8_t gun;
	if(gunId==NULL)
	{
		for(gun=0;gun<GUNNUM_MAX;gun++)
		{
			queueInit(&plc232_RxQue[gun]);
			CHAdeMO_232_TxData_Init(&rnlChademoEvsePara[gun]);
			CHAdeMO_232_RxData_Init(&rnlChademoEvccPara[gun]);
			CHAdeMO_232_TRCtrl_Init(&rnlChademoCommCtrl[gun]);
		}
	}
	else{
		queueInit(&plc232_RxQue[gunId]);
		CHAdeMO_232_TxData_Init(&rnlChademoEvsePara[gunId]);
		CHAdeMO_232_RxData_Init(&rnlChademoEvccPara[gunId]);
		CHAdeMO_232_TRCtrl_Init(&rnlChademoCommCtrl[gunId]);
	}
		
	
}
void CHAdeMO_232_TxData_Init(RNL_CHAdeMOEvsePara *p_tx)
{
	 p_tx->chargeType = CHAdeMO_Mode;
	 p_tx->reportStateType = CHAdeMO_PluginState;
	 p_tx->responseCode = OK;
	 p_tx->evseMaxCur = 600;	//Unit 0.1A
	 p_tx->evseMaxVol = 5000;	//Unit 0.1V
	 p_tx->evsePresentCur = 0;
	 p_tx->evsePresentVol = 0;
	 p_tx->evseProcess = Ongoing;
	 p_tx->evseStatus.StatusCode = EVSE_NotReady;
	 p_tx->currentLimitAchieved = 0;
	 p_tx->voltageLimitAchieved = 0;
}
void CHAdeMO_232_RxData_Init(RNL_CHAdeMOEvccPara *p_rx)
{
	memset(p_rx,0,sizeof(RNL_CHAdeMOEvccPara));
}

void CHAdeMO_232_TRCtrl_Init(RNL_CHAdeMOCommunicationCtrlS *commCtrl)
{
	commCtrl->chargingStep = 0;
	commCtrl->sendFlag.msgFlags = 0;
	commCtrl->rcvFlag.msgFlags = 0;
	commCtrl->overTimeFlag.msgFlags = 0;
	commCtrl->overTimeCtrl[CHADEMO_RPTINIT] 	= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_START] 		= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_SSETUP] 		= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_CHRGPARADISC]= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_CABLECHK] 	= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_POWERDELIV] 	= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_CURRDMD] 	= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_WELDDETECT] 	= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_SSTOP] 		= CHADEMOMSG_COUNTDOWN;
	commCtrl->overTimeCtrl[CHADEMO_ASTOP] 		= CHADEMOMSG_COUNTDOWN;
	
}


void CHAdeMO_232_RxProcess(uint8_t gunId, RNL_CHAdeMOEvsePara *p_tx, RNL_CHAdeMOEvccPara *p_rx, RNL_CHAdeMOCommunicationCtrlS *commCtrl)
{
	uint8_t msgID;
	uint8_t plc232RxBuf[RNL_CHADEMO_PLCMSG_MAXLEN];
	msgID = CHAdeMORs232MsgUnpack(plc232RxBuf, gunId);
	
	if(msgID)
	{
		#if defined (__RNL_CHADEMO_DEBUG__)
		if(gunId == GUNA)
		{
			printf("GUNA ");
		}
		else if(gunId == GUNB)
		{
			printf("GUNB ");
		}
		#endif
		switch(msgID)
		{
			case ReportInitRes_ID:
				CHAdeMO_ReportInitMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_START, gunId);
				break;
			case AllStopRes_ID:
				CHAdeMO_AllStopMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				break;
			case ReportStateRes_ID:
				CHAdeMO_ReportStateMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				break;
			case CHADEMO_SessionSetupReq_ID:
				CHAdeMO_SessionSetupMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_SSETUP, gunId);
				break;
			case CHADEMO_ChargeParameterDiscoveryReq_ID:
				CHAdeMO_ChargeParameterDiscoveryMsg_Analyse(plc232RxBuf, p_rx,  commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_CHRGPARADISC, gunId);
				break;
			case CHADEMO_CableCheckReq_ID:
				CHAdeMO_CableCheckMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_CABLECHK, gunId);
				break;
			case CHADEMO_PowerDeliveryReq_ID:
				CHAdeMO_PowerDeliveryMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_POWERDELIV, gunId);
				break;
			case CHADEMO_CurrentDemandReq_ID:
				CHAdeMO_CurrendDemandMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_CURRDMD, gunId);
				break;
			case CHADEMO_WeldingDetectionReq_ID:
				CHAdeMO_WeldingDetectionMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_WELDDETECT, gunId);
				break;
			case CHADEMO_SessionStopReq_ID:
				CHAdeMO_SessionStopMsg_Analyse(plc232RxBuf, p_tx, p_rx, commCtrl);
				RNL_SetChademoChargingStep(CHADEMO_SSTOP, gunId);
				break;
			case ReportSLAC_ID:
				CHAdeMO_ReportSLACMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				break;
			case ReportSDP_ID:
				CHAdeMO_ReportSDPMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				break;
			case ReportV2GCHA_ID:
				CHAdeMO_ReportV2GCHAMsg_Analyse(plc232RxBuf, p_rx, commCtrl);
				break;
			default:
				break;
		}
	}
	if(p_rx->chademoPlugin==1)
	{
		if((gunId==GUNA)&&(getChargerStatus(GUNA)!=CHARGER_BUSY))
		{
			setChargerStatus(GUNA,CHARGER_BUSY);
		}
		if((gunId==GUNB)&&(getChargerStatus(GUNB)!=CHARGER_BUSY))
		{
			setChargerStatus(GUNB,CHARGER_BUSY);
		}
	}
}

void CHAdeMO_RptInitProcess(uint8_t gunId)
{
	static uint32_t tickBase[GUNNUM_MAX] = {0};
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.rptInit==0)
	{
		if(timeoutCalc(tickBase[gunId],1000))
		{
			CHAdeMO_ReportInitReq(rnlChademoEvsePara[gunId],gunId);
			tickBase[gunId] = HAL_GetTick();
		}
	}
}
void CHAdeMO_StartProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].sendFlag.flagBit.start == 0)
	{
		CHAdeMO_StartReq(rnlChademoEvsePara[gunId],gunId);
		setModuleCtrl(gunId,2,POWER_ON|SET_VI,2000,10);
//		uuPowerModifyCtrlStatus(200, 1, UU_POWERON|UU_SET,gunId,1);
	}
}
void CHAdeMO_SesionSetupProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].sendFlag.flagBit.sSetup==0)
	{
		CHAdeMO_SessionSetupRes(rnlChademoEvsePara[gunId],gunId);
		
	}
}
void CHAdeMO_ChgParaDiscProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.chrgParaDisc==1)
	{
		rnlChademoEvsePara[gunId].evseStatus.StatusCode = EVSE_Ready;
		CHAdeMO_ChargeParameterDiscoveryRes(rnlChademoEvsePara[gunId],gunId);
		rnlChademoCommCtrl[gunId].rcvFlag.flagBit.chrgParaDisc = 0;
	
	}
}
void CHAdeMO_CableChkProcess(uint8_t gunId)
{
	static uint8_t cableChkFlag[GUNNUM_MAX] = {0};
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.cableChk==1)
	{
		//闭合直流输出接触器
		if((gunId==GUNB)&&(getShortPressSignal(AGUNDCCONTACTFIRST_STATUS)==0))
		{
			setKeyValueHandle(A_DC_CONTACTOR1_MODULE,1,0,0x00,0x00,NULL);
		}
		if((gunId==GUNB)&&(getShortPressSignal(BGUNDCCONTACTFIRST_STATUS)==0))
		{
			setKeyValueHandle(B_DC_CONTACTOR1_MODULE,1,0,0x00,0x00,NULL);
		}
		//模块调至车端最大电压
		setModuleCtrl(gunId,2,SET_VI,rnlChademoEvccPara[gunId].evMaxVol*10,10);
//		uuPowerModifyCtrlStatus(rnlChademoEvccPara[gunId].evMaxVol, 1, UU_POWERON|UU_SET,gunId,1);
		if(cableChkFlag[gunId]>29)
		{
			rnlChademoEvsePara[gunId].evseProcess = Finished;
			//绝缘检测完成，闭合D2
			if((gunId==GUNA)&&(getKeyValueHandle(A_CHADEMO_D2_MODULE)==GPIO_PIN_RESET))
			{
				setKeyValueHandle(A_CHADEMO_D2_MODULE,1,0,0x00,0x00,NULL);
			}
			if((gunId==GUNB)&&(getKeyValueHandle(B_CHADEMO_D2_MODULE)==GPIO_PIN_RESET))
			{
				setKeyValueHandle(A_CHADEMO_D2_MODULE,1,0,0x00,0x00,NULL);
			}
			cableChkFlag[gunId] = 0;
		}
		else
		{
			rnlChademoEvsePara[gunId].evseProcess = Ongoing;
			cableChkFlag[gunId]++;
		}
		CHAdeMO_CableCheckRes(&rnlChademoEvsePara[gunId],gunId);
		rnlChademoCommCtrl[gunId].rcvFlag.flagBit.cableChk = 0;
		
	}
}
void CHAdeMO_PowerDelivProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.powerdeliv==1)
	{
		rnlChademoEvsePara[gunId].responseCode = OK;
		rnlChademoEvsePara[gunId].evseStatus.StatusCode = EVSE_Ready;
		CHAdeMO_PowerDeliveryRes(&rnlChademoEvsePara[gunId],gunId);
		rnlChademoCommCtrl[gunId].rcvFlag.flagBit.powerdeliv = 0;
		
	}
}

void CHAdeMO_CurDemandProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.curDemd==1)
	{
		if(rnlChademoEvccPara[gunId].evTargetVol>rnlChademoEvsePara[gunId].evseMaxVol)//兼容性检测
		{
			rnlChademoEvsePara[gunId].evseStatus.StatusCode = EVSE_BatteryIncompatibility;
			RNL_SetChademoChargingStep(CHADEMO_ASTOP, gunId);
		}
		else
		{
			CHAdeMO_CurrendDemandRes(&rnlChademoEvsePara[gunId],gunId);
			rnlChademoCommCtrl[gunId].rcvFlag.flagBit.curDemd = 0;
			setModuleCtrl(gunId,2,SET_VI,rnlChademoEvccPara[gunId].evTargetVol*10,rnlChademoEvccPara[gunId].evTargetCur*10);
//			uuPowerModifyCtrlStatus(rnlChademoEvccPara[gunId].evTargetVol,rnlChademoEvccPara[gunId].evTargetCur, UU_SET,gunId,1);
		}
	}
}
void CHAdeMO_WeldingDetProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.weldDet==1)
	{
		CHAdeMO_WeldingDetectionRes(&rnlChademoEvsePara[gunId],gunId);
		rnlChademoCommCtrl[gunId].rcvFlag.flagBit.weldDet = 0;
	}
}
void CHAdeMO_SStopProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].rcvFlag.flagBit.sStop==1)
	{
		CHAdeMO_SessionStopRes(rnlChademoEvsePara[gunId],gunId);
		rnlChademoCommCtrl[gunId].rcvFlag.flagBit.sStop = 0;
		if(gunId==GUNA)
		{
			setKeyValueHandle(A_DC_CONTACTOR1_MODULE,0,0,0x00,0x00,NULL);
		}
		else if(gunId==GUNB)
		{
			setKeyValueHandle(B_DC_CONTACTOR1_MODULE,0,0,0x00,0x00,NULL);
		}
//		uuPowerModifyCtrlStatus(200, 1, UU_POWEROFF,gunId,1);
		setModuleCtrl(gunId,2,POWER_DOWN,0,0);
	}
}
void CHAdeMO_AStopProcess(uint8_t gunId)
{
	if(rnlChademoCommCtrl[gunId].sendFlag.flagBit.aStop==0)
	{
		CHAdeMO_AllStopReq(rnlChademoEvsePara[gunId],gunId);
//		uuPowerModifyCtrlStatus(200, 1, UU_POWEROFF,gunId,1);
		setModuleCtrl(gunId,2,POWER_DOWN,0,0);
		if(gunId==GUNA)
		{
			setKeyValueHandle(A_DC_CONTACTOR1_MODULE,0,0,0x00,0x00,NULL);
		}
		else if(gunId==GUNB)
		{
			setKeyValueHandle(B_DC_CONTACTOR1_MODULE,0,0,0x00,0x00,NULL);
		}
	}
}

// 瑞凯诺plc(CHAdeMO)充电阶段状态迁移函数
void RNL_SetChademoChargingStep(uint8_t gunId, uint8_t step)
{
	rnlChademoCommCtrl[gunId].chargingStep = step;
}

uint8_t RNL_GetChademoChargingStep(uint8_t gunId)
{
	return rnlChademoCommCtrl[gunId].chargingStep;
}

// 瑞凯诺PLC日标充电控制入口函数
void RNL_CHAdeMOChargingCtrlEntry(uint8_t gunId)
{
	uint8_t chargeStep;
	chargeStep = RNL_GetChademoChargingStep(gunId);
	CHAdeMO_232_RxProcess(gunId,&rnlChademoEvsePara[gunId],&rnlChademoEvccPara[gunId],&rnlChademoCommCtrl[gunId]);
	if(getChargerStatus(gunId)==CHARGER_BUSY)
	{
		switch(chargeStep)
		{
			case CHADEMO_RPTINIT:
				CHAdeMO_RptInitProcess(gunId);
				break;
			case CHADEMO_START:
				//开始
				CHAdeMO_StartProcess(gunId);
				break;
			case CHADEMO_SSETUP:
				//服务连接
				CHAdeMO_SesionSetupProcess(gunId);
				break;
			case CHADEMO_CHRGPARADISC:
				//交换充电参数
				CHAdeMO_ChgParaDiscProcess(gunId);
				break;
			case CHADEMO_CABLECHK:
				//绝缘检测(多次)
				CHAdeMO_CableChkProcess(gunId);
				break;
			case CHADEMO_POWERDELIV:
				//功率输出请求(开始充电一次，结束一次)
				CHAdeMO_PowerDelivProcess(gunId);
				break;
			case CHADEMO_CURRDMD:
				//电流需求(多次)
				CHAdeMO_CurDemandProcess(gunId);
				break;
			case CHADEMO_WELDDETECT:
				//焊接检测(多次)
				CHAdeMO_WeldingDetProcess(gunId);
				break;
			case CHADEMO_SSTOP:
				CHAdeMO_SStopProcess(gunId);
				break;
			case CHADEMO_ASTOP:
				CHAdeMO_AStopProcess(gunId);
				break; 
		}
	}
}
